package com.bee.shepherd.service.etl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.otter.canal.protocol.FlatMessage;
import com.bee.shepherd.entity.WechatGroupChatMsg;
import com.qunar.finance.nbdata.adapter.api.been.RequestParam;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.script.Script;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

@Service
public class WechatParamBuildService {

    private static final Logger logger = LoggerFactory.getLogger(WechatParamBuildService.class);

    @Value("${es.adapter..token}")
    private String token;
    @Value("${es.adapter.source}")
    private String source;

    private static final String INDEX = "shepherd_wechat_group_msg_v2";
    private static final String TYPE = "wechat_group_chat_msg";

    private RequestParam getRequestParam(){
        RequestParam requestParam = new RequestParam();

        requestParam.setToken(token);
        requestParam.setSource(source);

        requestParam.setIndex(INDEX);
        requestParam.setType(TYPE);

        return requestParam;
    }

    public RequestParam saveParam(FlatMessage message) {
        RequestParam requestParam = getRequestParam();

        requestParam.setId("" + message.getData().get(0).get("id"));

        Map<String,String> data = message.getData().get(0);

        updateTimeFormatter(data);

        requestParam.setDslCommand(JSON.toJSONString(data));

        return requestParam;
    }

    public RequestParam updateParam(FlatMessage message){

        Map<String,String> data = message.getData().get(0);

        updateTimeFormatter(data);

        String pkName = message.getPkNames().get(0);
        String id = data.get(pkName);

        RequestParam requestParam = getRequestParam();
        requestParam.setId(id);

        requestParam.setDslCommand(JSON.toJSONString(data));

        return requestParam;

    }

    public RequestParam updateByQueryParam(FlatMessage message) throws IOException {
        Set<String> fields = message.getOld().get(0).keySet();
        Map<String, String> data = message.getData().get(0);

        String pkName = message.getPkNames().get(0);

        String id = data.get(pkName);

        RequestParam requestParam = getRequestParam();
        requestParam.setId(id);

        updateTimeFormatter(data);

        XContentBuilder builder = jsonBuilder()
                .startObject()
                    .startObject("script");
                builder.field("inline",genInlineString(fields));
                buildInlineParam(fields,data,builder);
                builder.field("lang","painless")
                    .endObject()
                    .startObject("query")
                        .startObject("bool")
                            .startArray("must")
                                .startObject()
                                    .startObject("term")
                                        .field("id",id)
                                    .endObject()
                                .endObject()
                            .endArray()
                        .endObject()
                    .endObject()
                .endObject();

        String json = Strings.toString(builder);

        logger.info("dsl json:{}",json);

        requestParam.setDslCommand(json);

        return requestParam;

    }

    public RequestParam deleteParam(FlatMessage message){
        RequestParam requestParam = getRequestParam();

        Map<String,String> data = message.getData().get(0);
        String pkName = message.getPkNames().get(0);
        String id = data.get(pkName);
        requestParam.setId(id);

//        requestParam.setDslCommand(JSON.toJSONString(msg));
        return requestParam;
    }

    private void updateTimeFormatter(Map<String,String> data){
        if(StringUtils.isNotBlank(data.get("create_time"))){
            data.put("create_time",data.get("create_time").replace(' ', 'T'));
        }
        if(StringUtils.isNotBlank(data.get("update_time"))){
            data.put("update_time",data.get("update_time").replace(' ', 'T'));
        }
    }

    private String genInlineString(Set<String> fields){
        StringBuilder inlineBuilder = new StringBuilder();
        inlineBuilder.append("ctx._source.member_nick_name = params.member_nick_name;ctx._source.content = params.content");
        for (String field:fields){
            inlineBuilder.append("ctx._source.").append(field).append("=").append("params.").append(field).append(";");
        }
        return inlineBuilder.substring(0,inlineBuilder.length() - 1);
    }

    private void buildInlineParam(Set<String> fields,Map<String,String> data,XContentBuilder builder) throws IOException {
        builder.startObject("param");
        for (String field : fields){
            builder.field(field,data.get(field));
        }
        builder.endObject();
    }

    //TODO
    public List<RequestParam> batchSaveParam(List<FlatMessage> list) {

        return null;
    }
}
